package cn.huiyunche.driver.controller;

import cn.huiyunche.base.service.constant.RegularConstant;
import cn.huiyunche.base.service.enums.EnabledEnum;
import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.framework.security.JwtAuthenicationFilter;
import cn.huiyunche.base.service.framework.security.JwtUtils;
import cn.huiyunche.base.service.framework.utils.UserAgentUtils;
import cn.huiyunche.base.service.interfaces.SendMessageService;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.model.SUser;
import cn.huiyunche.base.service.vo.Result;
import cn.huiyunche.base.service.vo.UserVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import eu.bitwalker.useragentutils.DeviceType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;

@Controller
@RequestMapping("/login")
public class LoginController {
    private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private UserService userService = null;

    @Autowired
    private SendMessageService sendService = null;

    @Value("#{configProperties['secure.key']}")
    private String securrKey;

    private String getSecurrKey() {
        return this.securrKey;
    }

    private SendMessageService getSendMessageService() {
        return this.sendService;
    }

    private UserService getUserService() {
        return this.userService;
    }

    /**
     * @param phone    手机号
     * @param password 密码
     * @param usertype 用户类型（10为司机 20为货主，30为运输公司，40为托运企业，50为人送车）
     * @return
     * @Title: userLogin
     * @Description: 使用手机号和密码登录
     * @return: Result<String>
     */
    @RequestMapping(value = "/userlogin", method = RequestMethod.POST)
    @ResponseBody
    public Result<Object> userLogin(HttpServletRequest request, @RequestParam("phone") String phone, @RequestParam("password") String password, @RequestParam("usertype") String usertype, @RequestParam(value = "openid", required = false) String openid, @RequestParam(value = "uuid", required = false) String uuid, @RequestParam(value = "pushid", required = false) String pushid, @RequestParam(value = "clienttype", required = false) String clienttype, @RequestParam(value = "devicetype", required = false) String devicetype) throws Exception {
        LOGGER.info("LoginController.codeLogin params : {}, {}, {}, {}, {},{},{},{}", phone, password, usertype, openid, uuid, pushid, clienttype, devicetype);
        Result<Object> result = new Result<Object>(true, "登录成功!");
        if (StringUtils.isBlank(phone)) {
            throw new BusinessException("手机号不能为空");
        } else if (StringUtils.isBlank(openid) && StringUtils.isBlank(uuid)) {
            throw new BusinessException("openid或uuid不能为空");
        } else if (StringUtils.isBlank(password)) {
            throw new BusinessException("密码不能为空");
        } else if (StringUtils.isBlank(usertype)) {
            throw new BusinessException("用户类型不能为空");
        }
        //  判断用户可用不可用
        SUser checkUser = this.getUserService().getByPhone(phone, Arrays.asList(UserTypeEnum.SEND_DRIVER.getValue(), UserTypeEnum.CONSUMER_DRIVER.getValue()));
        if (null == checkUser) {
            result.setMessage("登录名或密码不正确");
            result.setSuccess(false);
            return result;
        }
        // 如果是人送车队司机，直接过滤
        if (checkUser.getUserType() == UserTypeEnum.CONSUMER_DRIVER.getValue()) {
            usertype = UserTypeEnum.CONSUMER_DRIVER.getValue() + "";
        }

        DeviceType device = UserAgentUtils.getDeviceType(request);
        SUser user = this.getUserService().signIn(phone, Integer.valueOf(usertype), password, device.getName(), openid, uuid, pushid, clienttype);
        UserVo uv = new UserVo(user.getId(), user.getPhone(), user.getPwd(), user.getOpenId(), user.getEnable().equals(EnabledEnum.T.getValue()) ? true : false, user.getUserType());
        String token = JwtUtils.generateToken(uv, this.getSecurrKey());
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("userType", user.getUserType() + "");
        map.put(JwtAuthenicationFilter.HEADER_AUTHORIZATION, JwtAuthenicationFilter.PREFIX_AUTHORIZATION + token);
        result.setData(map);
        return result;
    }

    /**
     * @param phone    手机号
     * @param usertype 用户类型（10为司机 20为货主，30为运输公司，40为托运企业，50为人送车）
     * @return
     * @Title: sendCaptchaforReset
     * @Description: 重置密码发送验证码
     * @return: Result<String>
     */
    @RequestMapping(value = "/resetcaptcha", method = RequestMethod.POST)
    @ResponseBody
    public Result<String> sendCaptchaforReset(@RequestParam("phone") String phone,
                                              @RequestParam("usertype") int usertype) {
        LOGGER.info("LoginController.sendCaptchaforReset params : {}, {}", phone, usertype);
        Result<String> result = new Result<String>(true, "发送成功！");
        if (StringUtils.isBlank(phone)) {
            throw new BusinessException("手机号不能为空!");
        }
        // 判断用户是否注册
        SUser uesr = this.getUserService().getByPhone(phone, Arrays.asList(UserTypeEnum.SEND_DRIVER.getValue(), UserTypeEnum.CONSUMER_DRIVER.getValue()));
        if (uesr == null) {
            throw new BusinessException("用户未注册或未激活！");
        }
        // 发送验证码
        result.setMessage(this.getSendMessageService().sendCaptcha(phone, usertype));
        return result;
    }

    /**
     * @param phone    手机号
     * @param password 密码
     * @param usertype 用户类型（10为司机 20为货主，30为运输公司，40为托运企业，50为人送车）
     * @param authcode 验证码
     * @return
     * @Title: restPwd
     * @Description: 重置密码
     * @return: Result<String>
     */
    @RequestMapping(value = "/resetpwd", method = RequestMethod.POST)
    @ResponseBody
    public Result<Object> resetPwd(@RequestParam("phone") String phone, @RequestParam("password") String password, @RequestParam("usertype") String usertype, @RequestParam("authcode") String authcode) throws Exception {
        LOGGER.info("LoginController.restPwd param : {}, {}, {}, {}", phone, password, usertype, authcode);
        Result<Object> result = new Result<Object>(true, "密码重置成功!");
        if (StringUtils.isBlank(phone)) {
            throw new BusinessException("手机号不能为空");
        } else if (StringUtils.isBlank(password)) {
            throw new BusinessException("密码不能为空");
        } else if (StringUtils.isBlank(authcode)) {
            throw new BusinessException("验证码不能为空");
        } else if (StringUtils.isBlank(usertype)) {
            throw new BusinessException("用户类型不能为空");
        } else if (password.length() > 14) {
            throw new BusinessException("密码长度为6-14位");
        } else if (password.length() < 6) {
            throw new BusinessException("密码长度为6-14位");
        } else if (!password.matches(RegularConstant.reg)) {
            throw new BusinessException("密码必须是数字和字母组合");
        }
        String authCode = null;
        try {
            authCode = this.getUserService().getAuthCode(phone, Integer.valueOf(usertype));
        } catch (Exception e1) {
            LOGGER.error("LoginController.restPwd error : {}", e1);
            throw new BusinessException("系统错误！");
        }
        if (authcode.equals(authCode)) {

            SUser uesr = this.getUserService().getByPhone(phone, Arrays.asList(UserTypeEnum.SEND_DRIVER.getValue(), UserTypeEnum.CONSUMER_DRIVER.getValue()));
            if (null != uesr) {
                this.getUserService().resetPwd(phone, uesr.getUserType(), password);
            }

            this.getUserService().resetPwd(phone, Integer.valueOf(usertype), password);

            //验证正确，移除redis中的验证码
            userService.removeAuthcode(phone + usertype);

        } else {
            throw new BusinessException("验证码错误!");
        }
        return result;
    }

}
